﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Microsoft.Web.Services2;
using Microsoft.Web.Services2.Security;
using Microsoft.Web.Services2.Security.Tokens;
using System.Data;
using System.Collections.Specialized;
using MySCM.Agent.TFS;
using MySCM.Common.Log;
using System.Windows.Forms; // for MessageBox
using System.Configuration;

namespace MySCM.Integration.Elementool.ElementoolIntegrator.Pull
{
    public class ElementoolClient
    {
        public Boolean PopMessageBox;
        public Boolean WriteLogFile;
        public string TfsUri;
        public string TfsLogin;
        public string TfsPassword;
        public string TfsDomain;
        public string TfsTeamProject;
        public string TfsWorkitemType;
        public string EtoolAccountName;
        public string EtoolUserName;
        public string EtoolPassword;
        private BugTrackingWse BTService;
        //private QuickReport[] RepList; // the list of available quick reports

        public ElementoolClient(string tfsUri, string tfsLogin, string tfsPassword, string tfsDomain, string tfsTeamProject, string tfsWorkitemType, string eToolAccountName, string eToolUserName, string eToolPassword)
        {
            try
            {
                PopMessageBox = false;
                WriteLogFile = true;
                TfsUri = tfsUri;
                TfsLogin = tfsLogin;
                TfsPassword = tfsPassword;
                TfsDomain = tfsDomain;
                TfsTeamProject = tfsTeamProject;
                TfsWorkitemType = tfsWorkitemType;
                EtoolAccountName = eToolAccountName;
                EtoolUserName = eToolUserName;
                EtoolPassword = eToolPassword;

                Connect();
            }
            catch (Exception ex)
            {
                if (WriteLogFile)
                    StaticLogger.WriteLog("Design", "Fatal", "Login Failed! - " + ex.Message);
                if (PopMessageBox)
                    MessageBox.Show("Login Failed! - " + ex.Message);
                return;
            }
        }


        private void Connect()
        {
            // send login info using Web Services Enhancement security tokens
            // (user name = "account\username")
            BTService = new BugTrackingWse();
            UsernameToken token = new UsernameToken(EtoolAccountName + @"\" + EtoolUserName, EtoolPassword, PasswordOption.SendHashed);
            BTService.RequestSoapContext.Security.Tokens.Add(token);
            BTService.RequestSoapContext.Security.Elements.Add(new MessageSignature(token));
            // this method does nothing but throws an exception if login info is incorrect
            BTService.LoginCheck();
        }


        public BugTrackingIssue GetIssue(int IssueNumber)
        {
            //Executes web method for retrieving issue details
            BugTrackingIssue issue = (BTService.GetIssueByNum(IssueNumber));
            //if issue exist
            if (issue != null)
            {
                if (PopMessageBox)
                    MessageBox.Show("Title      : " + GetIssueFieldBySystemName(issue, "title").Value + "\n" + "Assigned To: " + GetIssueFieldBySystemName(issue, "assigned_to").Value + "\n" + "Status     : " + GetIssueFieldBySystemName(issue, "Status").Value);
                if (WriteLogFile)
                    StaticLogger.WriteLog("Design", "Info", "Title      : " + GetIssueFieldBySystemName(issue, "title").Value + "\n" + "Assigned To: " + GetIssueFieldBySystemName(issue, "assigned_to").Value + "\n" + "Status     : " + GetIssueFieldBySystemName(issue, "Status").Value);
            }
            else
            {
                if (PopMessageBox)
                    MessageBox.Show("Issue #" + IssueNumber + " does not exist");
                if (WriteLogFile)
                    StaticLogger.WriteLog("Design", "Warning", "Issue #" + IssueNumber + " does not exist");
            }
            return issue;
        }


        public void GetReport(string ReportName)
        {
            //Executes web method for retrieving Quick Report
            QuickReport quickReport = null;
            foreach (QuickReport qp in BTService.GetQuickReportsList())
                if (String.Compare(qp.Name, ReportName, true) == 0) quickReport = qp;

            //if Report exist
            if (quickReport != null)
            {
                DataGrid dataGrid = new DataGrid();
                dataGrid.DataSource = BTService.ExecuteQuickReport(quickReport.ID);
                System.Data.DataSet myDataSet = new System.Data.DataSet("myDataSetName");
                myDataSet = BTService.ExecuteQuickReport(quickReport.ID);
                foreach (System.Data.DataTable table in myDataSet.Tables)
                {
                    foreach (System.Data.DataRow row in table.Rows)
                    {
                        foreach (System.Data.DataColumn column in table.Columns)
                        {
                            if (PopMessageBox)
                                MessageBox.Show(column.ColumnName + ":" + row[column].ToString());
                        }
                    }
                }
            }
            else
            {
                if (PopMessageBox)
                    MessageBox.Show("Report " + ReportName + " does not exist");
            }
        }


        public List<int> GetReportIssues(string ReportName)
        {
            List<int> issueNumbers = new List<int>();

            //Executes web method for retrieving Quick Report
            QuickReport quickReport = null;
            foreach (QuickReport qp in BTService.GetQuickReportsList())
                if (String.Compare(qp.Name, ReportName, true) == 0) quickReport = qp;

            //if Report exist
            if (quickReport != null)
            {
                DataGrid dataGrid = new DataGrid();
                dataGrid.DataSource = BTService.ExecuteQuickReport(quickReport.ID);
                System.Data.DataSet myDataSet = new System.Data.DataSet("myDataSetName");
                myDataSet = BTService.ExecuteQuickReport(quickReport.ID);
                int i = 0;
                int j = 0;
                int k = 0;
                foreach (System.Data.DataTable table in myDataSet.Tables)
                {
                    //MessageBox.Show("Table::" + i);
                    foreach (System.Data.DataRow row in table.Rows)
                    {
                        //MessageBox.Show("Row:" + j);
                        foreach (System.Data.DataColumn column in table.Columns)
                        {
                            if (PopMessageBox)
                                MessageBox.Show("i:" + i + " ***j:" + j + " ***k:" + k + " ***" + column.ColumnName + ":" + row[column].ToString());
                            if (String.Compare(column.ColumnName, "Issue Number", true) == 0)
                            {
                                if (PopMessageBox)
                                    MessageBox.Show("IssueName:" + row[column].ToString());
                                issueNumbers.Add(new int());
                                issueNumbers[j] = Convert.ToInt16(row[column]);
                            }
                            k++;
                        }
                        j++;
                    }
                    i++;
                }
            }
            else
            {
                if (PopMessageBox)
                    MessageBox.Show("Report " + ReportName + " does not exist");
                if (WriteLogFile)
                    StaticLogger.WriteLog("Design", "Fatal", "Report " + ReportName + " does not exist");
            }
            return issueNumbers;
        }


        // Field are identified by system name - "title","description","status",etc .
        // These names are given by elementool system, and are not diplayed to user anywhere on the web site
        // Users see only captions of fields which are customize by account admin.
        public IssueField GetIssueFieldBySystemName(BugTrackingIssue Issue, string FieldName)
        {
            foreach (IssueField fld in Issue.FieldsArray)
                if (String.Compare(fld.SystemName, FieldName, true) == 0) return fld;
            return null;
        }


        // Quick Reports
        private QuickReport GetReportByName(BugTrackingIssue Issue, string ReportName)
        {
            foreach (QuickReport qp in BTService.GetQuickReportsList())
                if (String.Compare(qp.Name, ReportName, true) == 0) return qp;
            return null;
        }


        public void UpdateTFS(int issueNumber, string fieldString)
        {
            // === Get the TFS login credential from the config file of team project collection
            TfsCredential tfsCredential = new TfsCredential();

            tfsCredential.login = TfsLogin;
            tfsCredential.password = TfsPassword;
            tfsCredential.domain = TfsDomain;
            if (PopMessageBox)
                MessageBox.Show(tfsCredential.login + "***" + tfsCredential.password + "***" + tfsCredential.domain);
            TFSAgent tfsAgent = new TFSAgent(tfsCredential.login, tfsCredential.password, tfsCredential.domain);
            tfsAgent.WriteLogFile = WriteLogFile;
            tfsAgent.PopMessageBox = PopMessageBox;

            string resultString = "";
            if (tfsAgent.ExternalWorkitemExists(TfsUri, TfsTeamProject, TfsWorkitemType, issueNumber))
                resultString = tfsAgent.UpdateExternalWorkitem(TfsUri, TfsTeamProject, TfsWorkitemType, issueNumber, fieldString);
            else
                resultString = tfsAgent.CreateExternalWorkitem(TfsUri, TfsTeamProject, TfsWorkitemType, issueNumber, fieldString);

            if (WriteLogFile)
            {
                StaticLogger.WriteLog("Design", "Info", resultString);
                StaticLogger.WriteLog("User", "Info", resultString);
            }
        }
    }
}
